/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../manager/plugin_manager.h"
#include "main_template.h"
#include <iostream>

#include "../UIComponentOtherRefreshCAbilty/ui_component_other_refresh_c_ability.h"

#define INVALID_PARAM 401

namespace ArkUICApiDemo {
static ArkUI_NodeHandle rootNode;
static ArkUI_NativeNodeAPI_1 *nodeAPI;
using FunctionCallBack = std::function<void(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle& rootNode)>;
static std::unordered_map<std::string, FunctionCallBack> xComponentToCreateNativeNode_ = {};
static bool hasInit = false;

void Initialize() {
    xComponentToCreateNativeNode_ = {
        // UIComponentRefreshC
        {"UIComponentRefreshC0010", std::bind(&UIComponentRefreshC::CreateNativeNodeRefreshC0010, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0010", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0010, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0020", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0020, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0030", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0030, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0040", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0040, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0050", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0050, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0060", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0060, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0070", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0070, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0080", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0080, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0090", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0090, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0100", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0100, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0110", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0110, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0120", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0120, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0130", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0130, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0140", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0140, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0150", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0150, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0160", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0160, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0170", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0170, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0180", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0180, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0190", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0190, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0200", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0200, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0210", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0210, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0220", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0220, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0230", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0230, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0240", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0240, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0250", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0250, std::placeholders::_1, std::placeholders::_2)},
        {"UIComponentOtherRefreshCAbilty0260", std::bind(&UIComponentRefreshC::CreateNativeNodeOtherRefreshCAbilty0260, std::placeholders::_1, std::placeholders::_2)},
        // add new native node...
    };
}

void DistributeAndCreateNodeByXComponentId(const std::string& componentId)
{
    if (!hasInit) {
        Initialize();
    }
    auto itor = xComponentToCreateNativeNode_.find(componentId);
    if (itor != xComponentToCreateNativeNode_.end()) {
        itor->second(nodeAPI, rootNode);
    } else {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DistributeEvent", "can not find xComponentId : %{public}s", componentId.c_str());
    }
    
}

napi_value MainTemplate::NativeCapiMainTest(napi_env env, napi_callback_info info)
{
    // 获取id
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    size_t length = 64;
    size_t strLength = 0;
    char xComponentID[64] = {0};
    napi_get_value_string_utf8(env, args[0], xComponentID, length, &strLength);
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
    // 按照XComponentId分发事件，并创建rootNode组件
    std::string xComponentIdStr(xComponentID);
    DistributeAndCreateNodeByXComponentId(xComponentIdStr);
    // 绑定NativeXComponent 和 rootNode
    OH_NativeXComponent_AttachNativeRootNode(PluginManager::GetInstance()->GetNativeXComponent(xComponentIdStr), rootNode);
    napi_value exports;
    napi_create_object(env, &exports);

    return exports;
}
} // namespace ArkUICApiDemo